Ext.CalendarDayPanel = Ext.extend(Ext.Panel,  {
	height: 720,
	events: [],
	firstEvent: 0,
    initComponent: function(){
        Ext.CalendarDayPanel.superclass.initComponent.call(this);
        
        this.addEvents(
            'eventdblclick'
        );
    },	

    onRender : function(ct, position){
        Ext.CalendarDayPanel.superclass.onRender.call(this, ct, position);
        this.body.addClass('calendar');
		for(var i = 0; i < 24; i++){
			var lDate = Date.parseDate(i+':00', 'G:i');
			this.body.createChild({
				tag: 'div',
				cls: 'cal_time',
				html: lDate.format(timeFormat),
				style: 'top: '+(i*30+1)+'px'
			});
		}
		
		this.recalculateEvents();
    },
	
	clearEvents : function(){
		for(var i = 0; i<this.events.length; i++){
			var lEvent = this.events[i];
			if(lEvent.element){
				lEvent.element.remove();
			}
			if(lEvent.shadow)
				lEvent.shadow.hide();
		}
		this.events = [];
	},
	
	setEvents : function(aEvents){
		this.clearEvents();
		this.events = aEvents;
		this.recalculateEvents();
	},
	
	recalculateEvents : function(){
		this.firstEvent = -1;
		var hasIntersections = function(aEvent1, aEvent2){
			if(aEvent1.start<=aEvent2.start && aEvent1.start+aEvent1.duration>aEvent2.start)
				return true;
			if(aEvent2.start<=aEvent1.start && aEvent2.start+aEvent2.duration>aEvent1.start)
				return true;
			return false;
		}
		
		for(var i = 0; i<this.events.length; i++){
			var lEvent = this.events[i];
			if(lEvent.duration>1440)
				lEvent.duration = 1440;
			if(lEvent.duration<45)
				lEvent.duration = 45;
			if(lEvent.start>1440-30)
				lEvent.start = 1440-30;
			if(lEvent.start+lEvent.duration>1440)
				lEvent.start = 1440-lEvent.duration;
			lEvent.size = 0;
			lEvent.position = 0;
			lEvent.neighbours = [];
			lEvent.parkFlag = 1;
			lEvent.group = 0;
			if((lEvent.start>0 && lEvent.start<this.firstEvent) || this.firstEvent==-1){
				this.firstEvent = lEvent.start;
			}	
		}
		
		if(this.firstEvent==-1)
			this.firstEvent = 8*60;//8 AM
		if(this.firstEvent % 60 > 0)
			this.firstEvent -= this.firstEvent % 60;
		for(var i = 0; i<this.events.length; i++){
			var lEvent = this.events[i];
			if(lEvent.parkFlag==1){//First check
				for(var j = i+1; j<this.events.length; j++){
					var lAnotherEvent = this.events[j];
					if(hasIntersections(lEvent, lAnotherEvent)){
						lEvent.neighbours[lEvent.neighbours.length] = lAnotherEvent;
						lAnotherEvent.neighbours[lAnotherEvent.neighbours.length] = lEvent;
					}
				}
				lEvent.parkFlag = 0;
//				console.log(lEvent.text+', neighbours: '+lEvent.neighbours.length);
			}
		}
		
		var lGroup = 0;
		
		var addChildrenToGroup = function(aGroup, aEvent){
//			console.log('Marking event '+aEvent.text+' as group: '+aGroup);
			aEvent.group = aGroup;
			for(var i = 0; i<aEvent.neighbours.length; i++){
				var lNeighbour = aEvent.neighbours[i];
				if(lNeighbour.group==0){
					addChildrenToGroup(aGroup, lNeighbour);
				}
			}
		}
		
		var calculateGroup = function(aGroup, aEventsArray){
			var lEverythingParked = false;
			var lLayer = 0;
			while(!lEverythingParked && lLayer<10){
//				console.log('Group: '+aGroup+', layer: '+lLayer);
				lLayer++;
				
				for(var i = 0; i<aEventsArray.length; i++){
					var lEvent = aEventsArray[i];
					if(lEvent.parkFlag!=0 || lEvent.group!=aGroup){//Already checked
						continue;
					}
//					console.log('Parking event '+lEvent.text+' on layer '+lLayer);
					lEvent.parkFlag = 2;//Park event on this layer
					lEvent.position = lLayer-1;
					for(var j = 0; j<lEvent.neighbours.length; j++){//Mark other events as already checked
						var lNeighbour = lEvent.neighbours[j];
						if(lNeighbour.parkFlag==0)
							lNeighbour.parkFlag = 1;//Not parked yet
					}
				}
				lEverythingParked = true;
				for(var i = 0; i<aEventsArray.length; i++){
					var lEvent = aEventsArray[i];
					if(lEvent.group!=aGroup)
						continue;
					if(lEvent.parkFlag==1){
						lEverythingParked = false;
						lEvent.parkFlag = 0;//For next step
					}
				}
			}
			
			//Calculate widths in group, set widths
			
			var lWidth = 1000/lLayer;
			
			for(var i = 0; i<aEventsArray.length; i++){
				var lEvent = aEventsArray[i];
				if(lEvent.group!=aGroup)
					continue;
				var lClosestLayer = lLayer;
				for(var j = 0; j<lEvent.neighbours.length; j++){//Look for closest neighbour to calc width
					var lNeighbour = lEvent.neighbours[j];
					if(lNeighbour.position>lEvent.position && lNeighbour.position<lClosestLayer)
						lClosestLayer = lNeighbour.position;
				}
//				console.log(lEvent.text+': pos: '+lEvent.position+', closest: '+lClosestLayer);
				lEvent.left = lEvent.position*lWidth;
				lEvent.width = (lClosestLayer-lEvent.position)*lWidth;
			}
		}
		
		for(var i = 0; i<this.events.length; i++){
			var lEvent = this.events[i];
			if(lEvent.group==0){
				addChildrenToGroup(++lGroup, lEvent);
				calculateGroup(lGroup, this.events);
			}
		}
	},
	
	eventDblClick : function(evt, element, config){
		this.fireEvent('eventdblclick', config.eventReference);
	},
	
	redrawEvents : function(){
		if(!this.el)
			return;
		var EVENTSPACE = 5;
		var HOURS_PADDING = 50;
		var RIGHT_PADDING = 5;
		var lWidth = this.getSize().width-HOURS_PADDING-RIGHT_PADDING;
		var lStep = lWidth/1000;
		
		for(var i = 0; i<this.events.length; i++){
			var lEvent = this.events[i];
			if(!lEvent.element){
				var lHtml = '<span class="cal_text"><b>'+lEvent.dates+'</b>&nbsp;'+escapeHTML(lEvent.text)+'</span>';
				if(lEvent.duration>60)
					lHtml += '<div class="crumb" style="color: #ffffff;">'+lEvent.crumb+'</div>';
				lEvent.element = this.body.createChild({
					tag: 'div',
					cls: 'cal_entry',
					html: lHtml
				});
				lEvent.element.eventReference = lEvent;
				lEvent.element.applyStyles({
					height: Math.floor(lEvent.duration/2-4),
					top: Math.floor(lEvent.start/2)
				});
				lEvent.element.on('dblclick', this.eventDblClick, this, {
					stopEvent: true,
					preventDefault: true,
					stopPropagation: true,
					eventReference: lEvent
				});
//				lEvent.element.show();
//				lEvent.element.fadeOut({ endOpacity: .8});
			}
//			console.log('left: '+(Math.floor(lEvent.left*lStep)+HOURS_PADDING)+', width: '+Math.floor(lEvent.width*lStep-4));
			lEvent.element.applyStyles({
				left: Math.floor(lEvent.left*lStep)+HOURS_PADDING,
				width: Math.floor(lEvent.width*lStep-4)
			});
//			lEvent.shadow.setZIndex(900);
//			lEvent.shadow.show(lEvent.element);
			
		}
	}
	
});
Ext.reg('calendarday', Ext.CalendarDayPanel);
